﻿using System;
using System.Collections.Generic;
using ActionLogic.Impl;
using BlockLogic.Impl;
using BlockLogic.Impl.Blocks.Checker;
using BlockLogic.Impl.Blocks.Checker.Enum;
using BlockLogic.Impl.Blocks.Checker.Strategy;
using BlockLogic.Impl.Blocks.Generator;
using BlockLogic.Impl.Blocks.ServiceDevice;
using BlockLogic.Impl.Blocks.ServiceDevice.Enum;
using BlockLogic.Impl.Enum;
using BlockLogic.Interface;
using BlockLogic.Interface.Blocks.Checker;
using BlockLogic.Interface.Blocks.Generator;
using BlockLogic.Interface.Blocks.ServiceDevice;
using ComputationalCore.Impl.RandomGenerator.Enum;
using ComputationalCore.Impl.RandomGenerator.Factory;

namespace GlobalLogic
{
    public class ProgramManager
    {
        private List<IGenerator> _generators;
        private List<ICheckerBlock> _checkers;
        private List<IServiceDevice> _servicedevice;
        public IList<ICheckerBlock> Checkers
        {
            get { return _checkers; }
        }

        public ProgramManager()
        {
            _generators = new List<IGenerator>();
            _generators.Add(new Generator(Guid.NewGuid(), BlockType.GENERATOR_UNIFORM));
            _generators.Add(new Generator(Guid.NewGuid(),BlockType.GENERATOR_UNIFORM)); 
            
            _checkers = new List<ICheckerBlock>();
            _checkers.Add(new CheckerBlock(Guid.NewGuid(), BlockType.CHECKER_UNIFORM));

            _servicedevice = new List<IServiceDevice>();
            _servicedevice.Add(new ServiceDeviceWithLoss(new Guid(), BlockType.SERVICE_DEVICE_WITH_LOSS_UNIFORM));
        }

        public void Run()
        {
            var executor = ActionExecutor.GetInstance();
            IRequestBuffer buffer = new RequestBuffer(Guid.NewGuid());
            var g0 = _generators[0];
            var g1 = _generators[1];
            var c0 = _checkers[0];
            var s0 = _servicedevice[0];
            
            var factory = RandomGeneratorFactory.GetInstance();
            g0.RandomGenerator = factory.Create(RandomGeneratorType.UNIFORM, 0, 10);
            g1.RandomGenerator = factory.Create(RandomGeneratorType.UNIFORM, 0, 10);
            s0.RandomGenerator = factory.Create(RandomGeneratorType.UNIFORM, 0, 10);
            s0.ServiceDiscipline = ServiceDiscipline.FIFO;
            g0.OutputBuffer = s0.InputBuffer;
            g1.OutputBuffer = s0.InputBuffer;
            s0.OutputBuffer = c0.InputBuffer;
            s0.UnServedBuffer = c0.InputBuffer;
            c0.Strategy = new UniformChecking();
            g0.Initialize();
            g1.Initialize();
            s0.Initialize();
            c0.Initialize();

            executor.Run();
            int k = 0;
            while (k++ < 50)
            {
                executor.Execute();

                while (!c0.InputBuffer.IsEmtpy())
                {
                    foreach (var r in c0.InputBuffer.Get())
                    {
                        Console.WriteLine(r.InitTime + " //Output & Unserved");
                    }
                }

                //if (c0.IsChecked)
                //{
                //    var param = c0.ReturnParameters;

                //    Console.WriteLine("Uniform:");
                //    Console.WriteLine("Degrees of freedom: " + param[CheckerParameter.DEGREES_OF_FREEDOM]);
                //    Console.WriteLine("Pearson criterion: " + param[CheckerParameter.PEARSON_CRITERION]);
                //    Console.WriteLine("Kolmogorov criterion: " + param[CheckerParameter.KOLMOGOROV_CRITERION]);
                //    Console.WriteLine("Mises criterion: " + param[CheckerParameter.MISES_CRITERTION]);
                //    Console.WriteLine("Point count: " + ((List<KeyValuePair<double, double>>)param[CheckerParameter.POINTS]).Count);
                //    Console.WriteLine("---------------------------");
                //    c0.IsChecked = false;
                //}
            }

        }
    }
}
